/*
 * Copyright (C) 2025 ameise <ameise.wang@gmail.com> - All Rights Reserved
 *
 * This file is part of e3time.
 *
 * e3time is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * e3time is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with e3time. If not, see <https://www.gnu.org/licenses/>.
 */

package e3time

import "time"

var Date = time.Date
var Unix = time.Unix
var UnixMilli = time.UnixMilli
var UnixMicro = time.UnixMicro
var Until = time.Until
var Sleep = time.Sleep
var FixedZone = time.FixedZone
var Since = time.Since

func After(d Duration) <-chan Trigger {
	wrap := WrapTimerHandler(1)
	NewTimer(wrap, nil, d)
	return wrap.C()
}

func IsSameDayUTC(t1, t2 Time) bool {
	y1, m1, d1 := t1.UTC().Date()
	y2, m2, d2 := t2.UTC().Date()
	return y1 == y2 && m1 == m2 && d1 == d2
}

func IsSameDayLocal(t1, t2 Time) bool {
	y1, m1, d1 := t1.Local().Date()
	y2, m2, d2 := t2.Local().Date()
	return y1 == y2 && m1 == m2 && d1 == d2
}

func IsSameDay(t1, t2 Time, loc *time.Location) bool {
	y1, m1, d1 := t1.In(loc).Date()
	y2, m2, d2 := t2.In(loc).Date()
	return y1 == y2 && m1 == m2 && d1 == d2
}

func IsSameMonthUTC(t1, t2 Time) bool {
	y1, m1, _ := t1.UTC().Date()
	y2, m2, _ := t2.UTC().Date()
	return y1 == y2 && m1 == m2
}

func IsSameMonthLocal(t1, t2 Time) bool {
	y1, m1, _ := t1.Local().Date()
	y2, m2, _ := t2.Local().Date()
	return y1 == y2 && m1 == m2
}

func IsSameMonth(t1, t2 Time, loc *time.Location) bool {
	y1, m1, _ := t1.In(loc).Date()
	y2, m2, _ := t2.In(loc).Date()
	return y1 == y2 && m1 == m2
}

func ZeroTimeUTC(t Time) Time {
	return t.Truncate(time.Hour * 24).In(t.Location())
}

func ZeroTimeLocal(t Time) Time {
	y1, m1, d1 := t.Local().Date()
	return time.Date(y1, m1, d1, 0, 0, 0, 0, time.Local).In(t.Location())
}

func ZeroTime(t Time, loc *time.Location) Time {
	y1, m1, d1 := t.In(loc).Date()
	return time.Date(y1, m1, d1, 0, 0, 0, 0, loc)
}

func DaysBetweenUTC(before, after Time) int64 {
	t1 := ZeroTimeUTC(before)
	t2 := ZeroTimeUTC(after)
	return int64(t2.Sub(t1).Hours() / 24)
}

func DaysBetweenLocal(before, after Time) int64 {
	t1 := ZeroTimeLocal(before)
	t2 := ZeroTimeLocal(after)
	return int64(t2.Sub(t1).Hours() / 24)
}

func DaysBetween(before, after Time, loc *time.Location) int64 {
	t1 := ZeroTime(before, loc)
	t2 := ZeroTime(after, loc)
	return int64(t2.Sub(t1).Hours() / 24)
}

func HoursBetween(before, after Time) int64 {
	return int64(after.UTC().Sub(before.UTC()).Hours())
}
